﻿using System;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Text;

namespace SIOsystem.Control
{
    class PrintHelper
    {
        private DataTable DataTable;
        private PrintDocument printDocument;
        private PageSetupDialog pageSetupDialog;
        private PrintPreviewDialog printPreviewDialog;

        private int rowCount = 0;
        private int colCount = 0;
        private int x = 0;
        private int y = 0;
        int i = 0;
        int[] arrColWidth = null;
        bool fixBigHead = false;
        bool fixHead = true;
        private int headGap = 120;
        private int rowGap = 30;
        private int leftMargin = 40;
        private Font font = new Font("宋体", 12);
        private Font bigheadFont = new Font("宋体", 17, FontStyle.Bold);
        private Font subbigheadFont = new Font("宋体", 14, FontStyle.Bold);
        private Font headingFont = new Font("宋体", 13);
        private Font captionFont = new Font("宋体", 12, FontStyle.Bold);
        private Brush brush = new SolidBrush(Color.Black);
        private string cellValue = string.Empty;



        public PrintHelper(DataTable DataTable)
        {
            this.DataTable = DataTable;
            printDocument = new PrintDocument();
            printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage);
        }

        private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            if (i == 0)
            {
                leftMargin = e.MarginBounds.Left;
                rowCount = DataTable.Rows.Count - 1;
                colCount = DataTable.Columns.Count - 1;
                arrColWidth = new int[DataTable.Columns.Count];
                foreach (DataColumn item in DataTable.Columns)
                {
                    arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
                }
                arrColWidth[1] = Math.Min(arrColWidth[1], 18);
                arrColWidth[2] = Math.Min(arrColWidth[2], 18);
                for (int j = 0; j < Math.Min(DataTable.Rows.Count, 500); j++)
                {
                    for (int k = 0; k < colCount; k++)
                    {
                        int intTemp = Encoding.GetEncoding(936).GetBytes(DataTable.Rows[j][k].ToString()).Length;
                        if (DataTable.Rows[j][k].GetType().ToString() == "System.DateTime")
                        {
                            intTemp = intTemp - 8;
                        }
                        if (intTemp > arrColWidth[k])
                        {
                            arrColWidth[k] = intTemp;
                        }
                    }
                }
            }
            y += e.MarginBounds.Top;
            if (i == 0 || fixBigHead)
            {
                //print bighead
                y += headGap;
            }
            int l = 10;
            if (i == 0 || fixHead)
            {
                //print headings
                x = leftMargin;
                for (int j = 0; j < colCount; j++)
                {
                    if (DataTable.Columns[j].ColumnName.Length > 0)
                    {
                        cellValue = DataTable.Columns[j].ColumnName;
                        e.Graphics.FillRectangle(new SolidBrush(Color.LightGray), x, y, arrColWidth[j] * l, rowGap);
                        e.Graphics.DrawRectangle(Pens.Black, x, y, arrColWidth[j] * l, rowGap);
                        e.Graphics.DrawString(cellValue, headingFont, brush, x, y + (rowGap - l) / 2);
                        x += arrColWidth[j] * l;
                    }
                }
            }
            //print all rows 
            for (; i < rowCount; i++)
            {
                y += rowGap;
                x = leftMargin;
                for (int j = 0; j < colCount; j++)
                {
                    if (DataTable.Columns[j].ColumnName.Length > 0) 
                    {
                        cellValue = DataTable.Rows[i][j].ToString();
                        if (j == 0) { cellValue = (i + 1).ToString(); }
                        e.Graphics.DrawRectangle(Pens.Black, x, y, arrColWidth[j] * l, rowGap);
                        e.Graphics.DrawString(cellValue, font, brush, x, y + (rowGap - l) / 2);
                        x += arrColWidth[j] * l;
                    }
                }
                if (y >= e.PageBounds.Height - (e.PageBounds.Bottom - e.MarginBounds.Bottom + rowGap))
                {
                    // 允許多頁打印
                    y = 0;
                    e.HasMorePages = true;
                    i++;
                    return;
                }
            }
            y += rowGap;
            for (int j = 0; j < colCount; j++)
            {
                e.Graphics.DrawString(" ", font, brush, x, y);
            }
            i = 0;
            e.HasMorePages = false;
        }

        public PrintDocument GetPrintDocument()
        {
            return printDocument;
        }

        public void Print()
        {
            try
            {
                pageSetupDialog = new PageSetupDialog();
                pageSetupDialog.Document = printDocument;
                pageSetupDialog.ShowDialog();
                printPreviewDialog = new PrintPreviewDialog();
                printPreviewDialog.Document = printDocument;
                printPreviewDialog.Height = 600;
                printPreviewDialog.Width = 800;
                printPreviewDialog.ShowDialog();
            }
            catch (Exception e)
            {
                throw new Exception("Printer error." + e.Message);
            }
        }
    }
}
